﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using BattleShips.Common;
using BattleShips.GameServers;
using System.Data;
using MySql.Data.MySqlClient;
using BattleShips.GameServers.BattleShipsGame;
using System.Net;

namespace TestServer {
    class GameServer : IGameServer {

        List<string> servers = new List<string>();
        List<GameClient> globalClients = new List<GameClient>();
        List<GameClient> idlePlayers = new List<GameClient>();
        List<GameClient> onlinePlayers = new List<GameClient>();
        List<GameClient> inWaitingPlayers = new List<GameClient>();
        Dictionary<uint, GameRoom> rooms = new Dictionary<uint, GameRoom>();
        Dictionary<uint, ClientGameState> gameState = new Dictionary<uint, ClientGameState>();

        public void RegisterServer(string serverDetails) {
            servers.Add(serverDetails);
        }

        public List<string> GetGameServers() {
            return servers;
        }

        public void RegisterClient(GameClient client) {
            globalClients.Add(client);
        }

        public List<GameClient> GetGlobalClients() {
            return globalClients;
        }

        public List<GameClient> GetIdlePlayers() {
            return idlePlayers;
        }

        public List<GameClient> GetOnlinePlayers() {
            return onlinePlayers;
        }

        public List<GameClient> GetWaitingPlayers() {
            return inWaitingPlayers;
        }

        public Dictionary<uint, GameRoom> GetRooms() {
            return rooms;
        }

        public void CreateNewRoom(GameRoom gameRoom, GameClient client) {
            if (globalClients.Contains(client)) {
                inWaitingPlayers.Add(client);
                client.PlayerStatus = "Waiting";
                client.InRoomName = gameRoom.RoomName;
            }
            rooms.Add(client.IdPlayer, gameRoom);
            client.clientGameState = new ClientGameState();
            client.InRoomId = client.IdPlayer;
        }

        public void Join(uint roomId, GameClient client) {
            rooms[roomId].JoinNewPlayer(client);
            rooms[roomId].RStatus = "Close";
            client.clientGameState = new ClientGameState();
            client.InRoomId = roomId;
        }
        public void OpponentFound(uint roomId, GameClient adminclient, GameClient normalclient) {
            string OpponentName = String.Empty; string competittors = String.Empty;
            Response rsp = new Response();
            rsp.CommandName = "opponentfound";
            rsp.Code = 0;
            foreach (var item in rooms[roomId].GetRoomClients()) {
                if (item.Value != adminclient) {
                    OpponentName = adminclient.Username;
                } else {
                    OpponentName = normalclient.Username;
                }
                rsp.Payload = OpponentName;
                item.Value.SendMessage(rsp.ToString());
            }
        }

        public Dictionary<uint, ClientGameState> GetClientGameState() {
            return gameState;
        }

        public void StartGame(uint id) {
            Response startGameResponse = new Response();
            startGameResponse.CommandName = "startgame";
            startGameResponse.Code = 0;
            startGameResponse.Payload = "start game; roomid : " + id;
            foreach (var item in rooms[id].GetRoomClients().Values) {
                item.SendMessage(startGameResponse.ToString());
                item.Playing = true;
            }
            SetWhoIsFirst(id);
            rooms[id].GameIsEnd = false;
        }
        public void HitChangePanel1(GameClient client, string field) {
            Response youwashit = new Response();
            youwashit.CommandName = "youwashit";
            youwashit.Code = 0;
            youwashit.Payload = field;
            client.SendMessage(youwashit.ToString());
        }
        public void HitChangePanel2(GameClient client, string field) {
            Response youhit = new Response();
            youhit.CommandName = "youhit";
            youhit.Code = 0;
            youhit.Payload = field;
            client.SendMessage(youhit.ToString());
        }
        public void MissChangePanel1(GameClient client, string field) {
            Response youwasmiss = new Response();
            youwasmiss.CommandName = "youwasmiss";
            youwasmiss.Code = 0;
            youwasmiss.Payload = field;
            client.SendMessage(youwasmiss.ToString());
        }
        public void MissChangePanel2(GameClient client, string field) {
            Response youmiss = new Response();
            youmiss.CommandName = "youmiss";
            youmiss.Code = 0;
            youmiss.Payload = field;
            client.SendMessage(youmiss.ToString());
        }

        public void GameEnd(GameClient Winner, GameClient Looser, string Reason) {
            if (Winner.Permission.Equals("GameRoomAdmin")) {
                rooms.Remove(Winner.IdPlayer);
            } else if (Looser.Permission.Equals("GameRoomAdmin")) {
                rooms.Remove(Looser.IdPlayer);
            }
            InitializeClientDefaultState(Winner);
            InitializeClientDefaultState(Looser);
            Response msg = new Response();
            msg.CommandName = "msg";
            if (Reason.Equals("surrender")) {
                msg.Payload = Looser.Username + " has proved to be a coward and abandon the game. So you win !";
            } else {
                msg.Payload = "You win . " + Looser.Username + " proved to be less skilled or less lucky. Good job commander.";
            }
            msg.Code = 0;
            Winner.SendMessage(msg.ToString());
            if (Reason.Equals("surrender")) {
                msg.Payload = "It is better to risk starving to death then surrender. If you give up on your dreams, what's left? - Jim Carrey. Game end.";
            } else {
                msg.Payload = "You lose . " + Winner.Username + " proved to be more skilled. It's all about luck :) . Next time commander ... maybe next time .";
            }
            Looser.SendMessage(msg.ToString());
            Response endGame = new Response();
            endGame.CommandName = "endgame";
            endGame.Code = 0;
            endGame.Payload = Winner.Username;
            Winner.SendMessage(endGame.ToString());
            endGame.Payload = Looser.Username;
            Looser.SendMessage(endGame.ToString());
        }

        public void InitializeClientDefaultState(GameClient client) {
            client.clientGameState.Initialize();
            client.InRoomId = 0;
            client.InRoomName = null;
            client.Permission = "NUser";
            client.PlayerStatus = "Idle";
        }

        public void SetWhoIsFirst(uint id) {
            List<GameClient> roomClients = new List<GameClient>();
            foreach (var item in rooms[id].GetRoomClients().Values) {
                roomClients.Add(item);
            }
            Random rnd = new Random();
            int r = rnd.Next(roomClients.Count);
            Response setturn = new Response();
            setturn.Code = 0;
            setturn.CommandName = "setturn";
            setturn.Payload = "yourturn";
            roomClients[r].SendMessage(setturn.ToString());
        }

        public void SetPlayerTurn(uint id, GameClient client) {
            Response waitturn = new Response();
            waitturn.Code = 0;
            waitturn.CommandName = "waitturn";
            waitturn.Payload = "waitturn";
            foreach (var item in rooms[id].GetRoomClients().Values) {
                if (item != client) {
                    item.SendMessage(waitturn.ToString());
                }
            }
            Response setturn = new Response();
            setturn.Code = 0;
            setturn.CommandName = "setturn";
            setturn.Payload = "yourturn";
            client.SendMessage(setturn.ToString());
        }

        public void ClientExitGame(GameClient client) {
            client.InitializeClientProp();
            if (globalClients.Contains(client)) {
                globalClients.Remove(client);
            } else if (onlinePlayers.Contains(client)) {
                onlinePlayers.Remove(client);
            } else if (idlePlayers.Contains(client)) {
                idlePlayers.Remove(client);
            } else if (inWaitingPlayers.Contains(client)) {
                inWaitingPlayers.Remove(client);
            }
        }

        public void Challenge(List<uint> idPlayer, Action<ChallengeResponse> onResponse) {
            throw new NotImplementedException();
        }

        public void RegisterChallengeListener(Action<Challenge> onChallenge) {
            throw new NotImplementedException();
        }

        public void RegisterStartGameListener(Action<IBattleShipsGame> onStartGame) {
            throw new NotImplementedException();
        }

        public void AcceptChallenge(uint idChallenge) {
            throw new NotImplementedException();
        }

        public void RejectChallenge(uint idChallenge) {
            throw new NotImplementedException();
        }
    }
}
